/**
 * 
 */
package edu.gatech.oad.mule.model;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

import edu.gatech.oad.mule.Game;
import edu.gatech.oad.mule.input.InputEvent;
import edu.gatech.oad.mule.input.interfaces.ControllerOwner;
import edu.gatech.oad.mule.model.GameStateMachine.GameState;
import edu.gatech.oad.mule.view.interfaces.RenderableMap;
import edu.gatech.oad.mule.view.interfaces.RenderablePlayer;
import edu.gatech.oad.mule.view.interfaces.RenderableTile;

/**
 * In this phase, an intro screen should be displayed for a period of time and
 * then the phase should end.
 * 
 * @author Dale Avery
 * 
 */
final class IntroPhase extends Phase {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7392733680386517495L;

	private static final GameState STATE = GameState.INTRO;

	private static final int INTRO_LENGTH = 2000;
	private Timer timer;
	private transient ActionListener listener;

	/**
	 * @param game
	 *            The game to be used for this phase
	 */
	public IntroPhase(Game game) {
		super(game);

		// Initialize timer for signaling the end of the phase.
		timer = new Timer(INTRO_LENGTH, null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.gatech.oad.mule.input.interfaces.InputListener#getActiveOwners()
	 */
	@Override
	public ControllerOwner[] getActiveOwners() {
		// Players not present in this phase.
		return new ControllerOwner[0];
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * edu.gatech.oad.mule.view.interfaces.RenderableGameDriver#getAllPlayers()
	 */
	@Override
	public RenderablePlayer[] getAllPlayers() {
		// Players not present in this phase.
		return new RenderablePlayer[0];
	}

	@Override
	public GameState getCorrespondingState() {
		return STATE;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * edu.gatech.oad.mule.view.interfaces.RenderableGameDriver#getCurrentMap()
	 */
	@Override
	public RenderableMap getCurrentMap() {
		// Map not present in this phase.
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * edu.gatech.oad.mule.view.interfaces.RenderableGameDriver#getCurrentPlayer
	 * ()
	 */
	@Override
	public RenderablePlayer getCurrentPlayer() {
		// Players not present in this phase.
		return null;
	}

	@Override
	public RenderableTile getCurrentTile() {
		// There is not tile selection in intro phase.
		return null;
	}

	@Override
	public RenderablePlayer[] getRankedPlayers() {
		// No players in intro phase.
		return new RenderablePlayer[0];
	}

	@Override
	public int getRemainingTime() {
		// Time left is irrelevant in Intro phase.
		return 0;
	}

	@Override
	public int getTurnLength() {
		// There are no turns in intro phase.
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * edu.gatech.oad.mule.input.interfaces.InputListener#inputEventHandler(
	 * edu.gatech.oad.mule.input.InputEvent)
	 */
	@Override
	public void inputEventHandler(InputEvent event) {
		// Intro phase does not use user input.
	}

	@Override
	public void reset() {
		// To reset the intro, reconfigure the timer.
		stop();
		timer.restart();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.gatech.oad.mule.model.Phase#start()
	 */
	@Override
	public void start() {
		// Build an action listener for timer.
		if (listener == null) {
			listener = new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					timerTick();
				}
			};
		}

		// Only add the action listener if it isn't already added.
		if (timer.getActionListeners().length == 0)
			timer.addActionListener(listener);

		timer.start();
		active = true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.gatech.oad.mule.model.Phase#stop()
	 */
	@Override
	public void stop() {
		active = false;
		timer.stop();
		// Remove action listeners for serialization.
		for (ActionListener l : timer.getActionListeners())
			timer.removeActionListener(l);
	}

	/**
	 * Handles timer tick events by ending the phase.
	 */
	private void timerTick() {
		stop();
		endPhase();
	}

}
